package main
/*
参考博客：
https://blog.csdn.net/zsspj12/article/details/103185711
https://github.com/alexbrainman/odbc
https://github.com/go-xorm/xorm （停止维护）
https://gitea.com/xorm/xorm/src/branch/master/README_CN.md
https://pkg.go.dev/xorm.io/xorm?tab=doc

达梦数据库必须开启ODBC连接：
https://blog.csdn.net/fengxiaozhenjay/article/details/104256229
https://blog.csdn.net/weixin_46323641/article/details/104298535

解决 golang.org/x/ 下包下载不下来的问题
https://studygolang.com/articles/19051?fr=sidebar
https://studygolang.com/articles/24075?fr=sidebar
*/
import (
	"fmt"
	_ "github.com/alexbrainman/odbc"  // google's odbc driver
	"github.com/go-xorm/xorm"
	"xorm.io/core"
	"github.com/axgle/mahonia"
)

type Address struct {
    Addressid int64 `xorm:"addressid"`
    Address1 string `xorm:"address1"`
    Address2 string `xorm:"address2"`
    City string `xorm:"city"`
    Postalcode string `xorm:"postalcode"`
}
// type Address struct {
//     Addressid int64 `xorm:addressid`
//     Address1 string `xorm:address1`
//     Address2 string `xorm:address2`
//     City string `xorm:city`
//     Postalcode string `xorm:postalcode`
// }

// func (address *Address)TableName() string {
// 	return `"person.address"`
// }

func TestSelect() {
	engine, err := xorm.NewEngine("odbc", "driver={DM8 ODBC DRIVER};server=127.0.0.1:5236;database=DM;uid=SYSDBA;pwd=123456789;charset=utf8")
	if err != nil {
		fmt.Println("new engine got error:", err)
		return
	}
	engine.ShowSQL(true)//控制台打印出生成的SQL语句；
	engine.Logger().SetLevel(core.LOG_DEBUG)
	if err := engine.Ping(); err != nil {
		fmt.Println("ping got error:", err)
		return
	}

	// 1) 远程查询
	results, err := engine.Query("select addressid, address1, address2, city, postalcode from person.address limit 5 offset 2")
	if err != nil {
		fmt.Println("查询出错:", err)
		return
	}
	for i, e := range results {
		fmt.Printf("%v\t", i)
		for k, v := range e {
			// 达梦数据库中文默认为gbk
			fmt.Printf("%v=%v\t", k, ConvertToString(string(v), "gbk", "utf-8"))
		}
		fmt.Printf("\n")
	}
	fmt.Println("*******************************")
	// 2） 使用struct 映射结果
	engine.SetMapper(core.SameMapper{})
	var sliceOfAddress []Address
	err = engine.Table("person.address").Limit(5, 0).Find(&sliceOfAddress)
	if err != nil {
		fmt.Println("查询出错:", err)
		return
	}
	for i,e := range sliceOfAddress {
		e.Address1 = ConvertToString(e.Address1, "gbk", "utf-8")
		e.Address2 = ConvertToString(e.Address2, "gbk", "utf-8")
		e.City = ConvertToString(e.City, "gbk", "utf-8")
		fmt.Printf("%v=%v\n", i, e)
	}

}
// 字符串解码函数
func ConvertToString(src string, srcCode string, tagCode string) string {
    srcCoder := mahonia.NewDecoder(srcCode)
    srcResult := srcCoder.ConvertString(src)
    tagCoder := mahonia.NewDecoder(tagCode)
    _, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
    result := string(cdata)
    return result
}

func main() {
	TestSelect()
}